<template>
  <div id="home">
    <!-- 顶部导航 -->
    <nav-bar class="home-nav">
      <div slot="center">购物街</div>
    </nav-bar>

    <!-- TODO: 选项卡2: 使用狸猫换太子计策来做吸顶功能 -->
    <!-- 在滚动位置 > 选项卡位置时, 进行显示 -->
    <tab-control
      :titles="['流行', '新款', '精选']"
      @tabHandler="tabHandler"
      ref="tabControl2"
      v-show="isTabConcrolFixed"
    />

    <!-- 使用scroll组件包裹 -->
    <scroll
      class="content"
      ref="betterScroll"
      :probe-type="3"
      @scroll="homeScrollHandler"
      :pull-up-load="true"
      @pullingUp="homePullUpLoadHandler"
    >
      <!-- 轮播 -->
      <home-swiper
        :bannerList="bannerList"
        @swiperImageLoad="homeSwiperImgLoad"
      />

      <!-- 推荐 -->
      <home-recommend-view :recommendList="recommendList" />

      <!-- 特色 -->
      <home-feature-view />

      <!-- 选项卡1: 在滚动位置 < 选项卡位置时显示 -->
      <tab-control
        :titles="['流行', '新款', '精选']"
        @tabHandler="tabHandler"
        ref="tabControl1"
        v-show="!isTabConcrolFixed"
      />

      <!-- TODO: (难点)选项卡对应的视图组件 -->
      <goods-list :goods-list="showGoods" />
    </scroll>

    <!-- 返回顶部 -->
    <!-- TODO: 当监听组件的原生事件时需要使用 .native修饰符 -->
    <back-top @click.native="backHandler" v-show="showBackBtn" />
  </div>
</template>

<script>
// 子组件
import HomeSwiper from './childrenComponents/HomeSwiper.vue'
import HomeRecommendView from './childrenComponents/HomeRecommendView.vue'
import HomeFeatureView from './childrenComponents/HomeFeatureView.vue'

// 公共组件
import NavBar from 'components/common/NavBar/NavBar.vue'
import TabControl from 'components/content/TabControl/TabControl.vue'
import GoodsList from 'components/content/Goods/GoodsList.vue'

// 滚动组件
import Scroll from 'components/common/Scroll/Scroll.vue'

// 网络请求
import { getHomeMultidata, getHomeGoods } from 'network/home'

// 工具函数
import { itemListMixin, backTopMixin } from 'utils/mixin'
import { POP, NEW, SELL } from 'utils/const'

export default {
  name: 'Home',
  props: {},
  data () {
    return {
      // 轮播图数据
      bannerList: [],
      // 推荐列表数据
      recommendList: [],
      // 流行 新款 精选
      goods: {
        pop: { page: 0, list: [] },
        new: { page: 0, list: [] },
        sell: { page: 0, list: [] }
      },
      // 查询显示数据的变量, 默认是pop
      currentType: 'pop',
      // 滚动显示位置
      scrollPosition: 0,
      // 选项卡位置
      controlPosition: 0,
      // 是否吸顶
      isTabConcrolFixed: false,
      // 记录滚动的位置Y值
      saveY: 0
    }
  },
  created () {
    // 1-请求多个数据
    this.getHomeMultidata()

    // 2-请求商品数据
    this.getHomeGoods(POP)
    this.getHomeGoods(NEW)
    this.getHomeGoods(SELL)

    // console.log(this.$route)
  },
  mounted () {
    // TODO: 使用混入后不再需要, 下方这些代码:
    /**
     * 在 detail, home页面中都有监听全局事件的代码, 将这些代码抽离出去
     */
    // // TODO: (一): (下拉刷新)使用防抖函数对refresh函数进行防抖优化(它重复执行了三十次), 不要加小括号, 小括号是执行函数了
    // // 接收返回的函数,再次执行它
    // const refresh = debounce(this.$refs.betterScroll.refresh, 50)
    // // 给itemImgLoad绑定名字
    // this.homeImageLoad = () => {
    //   // 当所有的图片加载完毕后, 重新计算一次scrollHeight高度
    //   refresh() // 大部分情况下执行了一次, 性能开销变小了
    //   // 这样写: this.$refs.betterScroll.refresh()  执行了30次
    // }
    // // TODO: 3-开启事件总线监听: goddslistitem中的图片加载完成
    // this.$bus.$on('itemImgLoad', this.homeImageLoad)
  },
  updated () {},
  mixins: [itemListMixin, backTopMixin],
  destroyed () {
    console.log('home组件销毁了')
  },
  // 使用kepp-alive之后会有的两个钩子函数
  // 活跃
  activated () {
    // 定位到保存的位置(重新计算位置,再定位)
    this.$refs.betterScroll.refresh()
    // 当前组件再次活跃的时候, 滚动到保存位置的地方, 延时0
    this.$refs.betterScroll.scrollTo(0, this.saveY, 0)
  },
  // 失活,保存位置
  deactivated () {
    this.saveY = this.$refs.betterScroll.getCurrentY()

    // 解除绑定的事件总线: 必须需要两个参数: 1-事件 2-函数
    this.$bus.$off('itemImgLoad', this.itemImglistener)
  },
  computed: {
    // 展示商品
    showGoods () {
      return this.goods[this.currentType].list
    },

    // 展示返回顶部按钮
    showBackBtn () {
      // 判断当前文档滚动的位置, 是否大于tab选项卡的位置
      return this.scrollPosition >= this.controlPosition
    }
  },
  methods: {
    /**
     * 网络请求相关
     */
    getHomeMultidata () {
      // 1-请求多个数据
      getHomeMultidata().then((res) => {
        // 在组件创建完毕之后马上发网络请求
        // console.log(res)
        this.bannerList = res.data.banner.list
        this.recommendList = res.data.recommend.list
      })
    },
    // TODO: 非常重要的思想
    getHomeGoods (type) {
      // 动态获取页码参数: 默认是0, 请求下一页的数据
      const page = this.goods[type].page + 1

      getHomeGoods(type, page).then((res) => {
        // console.log(res)
        // 将数据保存
        this.goods[type].list.push(...res.data.list)
        // 将当前类型的页码加1(下一次加载的时候,还得传过去)
        this.goods[type].page += 1

        // 请求发送完后重新开启上拉加载更多
        this.$refs.betterScroll.finishPullUp()
      })
    },
    /**
     * 事件监听相关
     */
    // 点击选项卡切换视图
    tabHandler (index) {
      // console.log(index)
      switch (index) {
        case 0:
          this.currentType = POP
          break
        case 1:
          this.currentType = NEW
          break
        case 2:
          this.currentType = SELL
          break
      }
      // TODO: 让两个tabcontrol状态同步(后期使用store做)
      this.$refs.tabControl1.currentIndex = index
      this.$refs.tabControl2.currentIndex = index
    },

    // back组件传递回来的事件: 不使用这种方式
    // backHanlder () {
    //   console.log(this.$refs.betterScroll)
    //   // 返回了顶部(通过refs用scroll组件中的bs实例, 调用scrollTo方法)
    //   this.$refs.betterScroll.bs.scrollTo(0, 0)
    // }

    // 第二种方式: 推荐使用(抽离混入中)

    // 监听组件滚动的位置
    homeScrollHandler (position) {
      // console.log(position.y)
      // TODO: 1.判断backTop是否显示
      let positionY = Math.abs(position.y)
      this.scrollPosition = positionY

      // TODO: 2.决定TabControl是否吸顶(position.y > this.controlPosition)
      this.isTabConcrolFixed = positionY > this.controlPosition
    },
    // TODO: 监听上拉加载更多, bs是scroll组件传递过来的better-scroll对象
    homePullUpLoadHandler () {
      // console.log('上拉加载更多')
      // // 发送下一次请求
      this.getHomeGoods(this.currentType)
    },
    // 通过轮播图加载完毕(只需要一张加载完毕)来获得元素的位置
    homeSwiperImgLoad () {
      // 所有的组件都有一个$el属性: 用于获取组件中的元素
      this.controlPosition = this.$refs.tabControl1.$el.offsetTop - 40
    }
  },
  watch: {},
  components: {
    NavBar,
    HomeSwiper,
    HomeRecommendView,
    HomeFeatureView,
    TabControl,
    GoodsList,
    Scroll
  }
}
</script>

<style lang="less" scoped>
#home {
  // padding-top: 44px;
  .home-nav {
    // 使用css变量
    background-color: var(--color-tint);
    color: #fff;

    // position: fixed;
    // left: 0;
    // right: 0;
    // top: 0;
    // z-index: 9;
  }

  .content {
    // TODO: css3: 新增特性,计算, 用视口高度 - (导航栏高度 + tabbar高度)
    height: calc(100vh - 93px);
    overflow: hidden;
  }

  /* 媒体查询 */
  @media screen and (min-width: 319px) and (max-width: 374px) {
    .content {
      height: calc(100vh - 88px);
    }
  }
}
</style>
